﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Util
{
    public class EnDecryptionUtil
    {
        private readonly static string sKey = AppConfigUtil.ReadAppSettings("EnDecrypKey");

        #region RSA加解密
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string RSAEncryption(string code)
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = "xybs";//密匙容器的名称，保持加密解密一致才能解密成功
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
                byte[] plaindata = Encoding.Default.GetBytes(code);//将要加密的字符串转换为字节数组
                byte[] encryptdata = rsa.Encrypt(plaindata, false);//将加密后的字节数据转换为新的加密字节数组
                return Convert.ToBase64String(encryptdata);//将加密后的字节数组转换为字符串
            }
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string RSADecrypt(string code)
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = "xybs";
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
                byte[] encryptdata = Convert.FromBase64String(code);
                byte[] decryptdata = rsa.Decrypt(encryptdata, false);
                return Encoding.Default.GetString(decryptdata);
            }
        }
        #endregion

        #region DES加解密
        /// <summary> 
        ///  DES加密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <returns></returns> 
        public static string DESEncryption(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                byte[] inputByteArray;
                inputByteArray = System.Text.Encoding.Default.GetBytes(Text);
                var sKeyb = AppSettingUtil.EnDecrypKey;
                //string md5SKey = Get32MD5One(MD5Encryption.MD5Encrypt(sKey)).Substring(0, 8);
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt(sKeyb)).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                System.Text.StringBuilder ret = new System.Text.StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                return ret.ToString();
            }
            catch { return "error"; }
        }

        /// <summary> 
        /// DES解密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecrypt(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }

                //string md5SKey = Get32MD5One(MD5Encryption.MD5Encrypt(sKey)).Substring(0, 8);
                var sKeyb = AppSettingUtil.EnDecrypKey;
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt(sKeyb)).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            catch { return "error"; }
        }

        /// <summary> 
        /// DES解密数据(根据前端加密信息)
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecryptbyqd(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt("29DAAD0A66C62BA3")).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            catch { return "error"; }
        }

        /// <summary> 
        /// DES解密数据(配合前端重新加密) 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecryptbandDESDecrypt(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt("29DAAD0A66C62BA3")).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                var data = System.Text.Encoding.Default.GetString(ms.ToArray());
                return DESEncryption(data);
            }
            catch { return "error"; }
        }

        /// <summary> 
        /// DES解密数据(根据前端加密key返回原来后端) 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecryptb(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt("29DAAD0A66C62BA3")).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                var data = System.Text.Encoding.Default.GetString(ms.ToArray());
                return DESDecrypt(data);
            }
            catch { return "error"; }
        }

        /// <summary> 
        /// DES解密数据(配合前端重新加密) 用于前端检测密码复杂性
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecryptbandDESDecryptb(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt("gpsysweb")).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                var data = System.Text.Encoding.Default.GetString(ms.ToArray());
                return DESEncryptionb(data);
            }
            catch { return "error"; }
        }

        /// <summary> 
        ///  DES加密数据（用于前端）
        /// </summary> 
        /// <param name="Text"></param> 
        /// <returns></returns> 
        public static string DESEncryptionb(string Text)
        {
            try
            {
                System.Security.Cryptography.DESCryptoServiceProvider des = new System.Security.Cryptography.DESCryptoServiceProvider();
                byte[] inputByteArray;
                inputByteArray = System.Text.Encoding.Default.GetBytes(Text);
                string md5SKey = Get32MD5One(EnDecryptionUtil.MD5Encrypt("29DAAD0A66C62BA3")).Substring(0, 8);
                des.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, des.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                System.Text.StringBuilder ret = new System.Text.StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                return ret.ToString();
            }
            catch { return "error"; }
        }

        #endregion

        #region MD5加密
        public static string MD5Encrypt(string phrase)
        {
            UTF8Encoding encoder = new UTF8Encoding();
            MD5CryptoServiceProvider md5hasher = new MD5CryptoServiceProvider();
            byte[] hashedDataBytes = md5hasher.ComputeHash(encoder.GetBytes(phrase));
            return byteArrayToString(hashedDataBytes);
        }

        private static string byteArrayToString(byte[] inputArray)
        {
            StringBuilder output = new StringBuilder("");

            for (int i = 0; i < inputArray.Length; i++)
            {
                output.Append(inputArray[i].ToString("X2"));
            }

            return output.ToString();
        }

        /// <summary>
        /// 获取16位md5加密
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Get16MD5One(string source)
        {
            using (System.Security.Cryptography.MD5 md5Hash = System.Security.Cryptography.MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(System.Text.Encoding.UTF8.GetBytes(source));
                //转换成字符串，并取9到25位
                string sBuilder = BitConverter.ToString(data, 4, 8);
                //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符，需要去除掉
                sBuilder = sBuilder.Replace("-", "");
                return sBuilder.ToString().ToUpper();
            }
        }

        /// <summary>
        /// 此代码示例通过创建哈希字符串适用于任何 MD5 哈希函数 （在任何平台） 上创建 32 个字符的十六进制格式哈希字符串
        /// 官网案例改编
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Get32MD5One(string source)
        {
            using (System.Security.Cryptography.MD5 md5Hash = System.Security.Cryptography.MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(System.Text.Encoding.UTF8.GetBytes(source));
                System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }

                string hash = sBuilder.ToString();
                return hash.ToUpper();
            }
        }

        //// <summary>
        /// </summary>
        /// <param name="strSource">需要加密的明文</param>
        /// <returns>返回32位加密结果，该结果取32位加密结果的第9位到25位</returns>
        public static string Get32MD5Two(string source)
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            //获取密文字节数组
            byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source));
            //转换成字符串，32位
            string strResult = BitConverter.ToString(bytResult);
            //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符，需要去除掉
            strResult = strResult.Replace("-", "");
            return strResult.ToUpper();
        }

        #endregion

        #region AES加密解密

        private static string aeskey = "4aWxt2yUVMZidvuSETjCYhRe09s38AXc";
        private static string aesiv = "6LK9mqaPG58AXnis7JzSfF==";
        /// <summary>
        ///  加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="data">要被加密的明文</param>
        /// <returns>密文base64</returns>
        public static string AESEncrypt(string data)
        {
            if (!string.IsNullOrWhiteSpace(data))
            {
                byte[] encryData = Encoding.UTF8.GetBytes(data);
                Aes rijndaelCipher = Aes.Create();
                rijndaelCipher.Key = Convert.FromBase64String(aeskey);
                rijndaelCipher.IV = Convert.FromBase64String(aesiv);
                rijndaelCipher.Mode = CipherMode.CBC;
                rijndaelCipher.Padding = PaddingMode.PKCS7;
                ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
                byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
                string result = Convert.ToBase64String(plainText);
                return result;
            }
            else
            {
                return data;
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static string AESDecrypt(string data)
        {
            if (!string.IsNullOrWhiteSpace(data))
            {
                byte[] encryData = Convert.FromBase64String(data);
                Aes rijndaelCipher = Aes.Create();
                rijndaelCipher.Key = Convert.FromBase64String(aeskey);
                rijndaelCipher.IV = Convert.FromBase64String(aesiv);
                rijndaelCipher.Mode = CipherMode.CBC;
                rijndaelCipher.Padding = PaddingMode.PKCS7;
                ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
                byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
                string result = Encoding.UTF8.GetString(plainText);
                return result;
            }
            else
            {
                return data;
            }
        }

        /// <summary>
        ///  AES 加密
        /// </summary>
        /// <param name="str">明文（待加密）</param>
        /// <returns></returns>
        public static string AesEncrypt(string str)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(aeskey),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform cTransform = rm.CreateEncryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Convert.ToBase64String(resultArray);
        }

        /// <summary>
        ///  AES 解密
        /// </summary>
        /// <param name="str">明文（待解密）</param>
        /// <param name="key">密文</param>
        /// <returns></returns>
        public static string AesDecrypt(string str)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Convert.FromBase64String(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(aeskey),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform cTransform = rm.CreateDecryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Encoding.UTF8.GetString(resultArray);
        }
        #endregion

        #region SHA为不可逆加密方式
        public static string SHA1Encrypt(string Txt)
        {
            var bytes = System.Text.Encoding.Default.GetBytes(Txt);
            var SHA = new System.Security.Cryptography.SHA1CryptoServiceProvider();
            var encryptbytes = SHA.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public static string SHA256Encrypt(string Txt)
        {
            var bytes = System.Text.Encoding.Default.GetBytes(Txt);
            var SHA256 = new System.Security.Cryptography.SHA256CryptoServiceProvider();
            var encryptbytes = SHA256.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public static string SHA384Encrypt(string Txt)
        {
            var bytes = System.Text.Encoding.Default.GetBytes(Txt);
            var SHA384 = new System.Security.Cryptography.SHA384CryptoServiceProvider();
            var encryptbytes = SHA384.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public string SHA512Encrypt(string Txt)
        {
            var bytes = System.Text.Encoding.Default.GetBytes(Txt);
            var SHA512 = new System.Security.Cryptography.SHA512CryptoServiceProvider();
            var encryptbytes = SHA512.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        #endregion
    }
}
